<template>
  <div
    class="WidgetConfigNode"
    :class="{
      'is-selected' : isSelected,
      'is-selected-ancestor': isSelectedAncestor
    }"
    @click.stop="handleClick"
  >
    <div class="label">
      <span class="button">
        <font-awesome-icon
          class="button-icon"
          :icon="['fa', 'eye']"
        />
      </span>
      <span class="button">
        <font-awesome-icon
          class="button-icon lock"
          :icon="['fa', 'lock']"
        />
      </span>
      <span
        class="title"
        :style="{ 'padding-left': level * 15 + 'px' }"
      >
        <span
          class="expand-button"
          v-if="hasChildren"
          @click="expanded = !expanded"
        >
          <font-awesome-icon
            v-if="expanded"
            class="button-icon"
            :icon="['fa', 'chevron-down']"
          />
          <font-awesome-icon
            v-else
            class="button-icon"
            :icon="['fa', 'chevron-right']"
          />
        </span>
        <span class="expand-button" v-else></span>
        <span class="name"><TxtEditor trigger-mode="dbclick" v-model="widgetConfig.name" /></span>
        <span class="select-handler">
          <font-awesome-icon
            class="select-handler-icon"
            :icon="['far', 'square']"
          />
        </span>
      </span>
    </div>
    <div class="children" v-show="expanded">
      <vue-drag
        class="scroll-view"
        group="widgetConfigs"
        handle=".label"
        v-model="children"
        :bubbleScroll="false"
        :animation="150"
        @change="handleChange"
      >
        <WidgetConfigNode
          v-for="child in children"
          :key="child.id"
          :widgetConfig="child"
          :level="level+1"
        ></WidgetConfigNode>
      </vue-drag>
    </div>
  </div>
</template>
<script lang="ts">
import { Component, Vue, Prop, Inject } from 'vue-property-decorator'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import WidgetConfig from '@/core/model/WidgetConfig';
import ApplicationEditor from '@/components/application-editor/ApplicationEditor.vue'
import Hierarchy from './Hierarchy.vue';
import draggable from 'vuedraggable'
import TxtEditor from '@/components/common/ui/TxtEditor.vue'

@Component({
  components: {
    FontAwesomeIcon,
    TxtEditor,
    'vue-drag': draggable,
  }
})
export default class WidgetConfigNode extends Vue {
  @Inject('app-editor')
  public appEditor!: ApplicationEditor

  @Inject('hierarchy')
  public hierarchy!: Hierarchy

  @Prop()
  public widgetConfig!: WidgetConfig

  @Prop({ default: 0 })
  public level!: number

  private expanded = false

  private get fileHandler() {
    return this.hierarchy.fileHandler
  }

  private get widgetDefinition() {
    return this.appEditor.getWidgetDefinitionBytag(this.widgetConfig._widgetTag)
  }

  private get children() {
    return this.widgetConfig.children
  }

  private set children(children: WidgetConfig[]) {
    this.widgetConfig.children = children
  }

  private get hasChildren() {
    return this.children.length > 0
  }

  private get isSelected() {
    return this.fileHandler?.isSelectedWidgetConfigId(this.widgetConfig.id)
  }

  private get isSelectedAncestor() {
    return this.fileHandler?.isSelectedAncestorId(this.widgetConfig.id)
  }

  private handleClick(event: MouseEvent) {
    this.fileHandler?.selectWidgetConfig(this.widgetConfig.id, event.ctrlKey)
  }

  private handleChange ({ added }: { added: { element: WidgetConfig } }) {
    if (added) {
      const parentWidget = this.widgetConfig
      const widgetConfig = added.element as WidgetConfig
      const {x, y} = widgetConfig.getAbsolutePosition()
      const {x: x0, y: y0} = parentWidget.getAbsolutePosition()
      widgetConfig.base.x = x - x0
      widgetConfig.base.y = y - y0
      widgetConfig.parentWidget = parentWidget
    }
    if (
      this.widgetDefinition?.isWidgetGroup &&
      this.children.length === 0
    ) {
      this.hierarchy.fileHandler?.deleteWidgetConfigById(this.widgetConfig.id)
    }
  }
}
</script>
<style scoped lang="scss">
@import '~@/style/variables.scss';
.WidgetConfigNode {
  .label {
    position: relative;
    height: 27px;
    line-height: 27px;
    cursor: pointer;
    white-space: nowrap;
    border-bottom: solid 1px rgba($border-color, 0.5);
    overflow: hidden;
  }

  .label:hover {
    background: rgba(0,0,0,0.25);
  }

  &.is-selected>.label {
    background: rgba($primary-color,0.25);
  }

  .label .button {
    display: inline-block;
    width: 26px;
    height: 26px;
    text-align: center;
    border-right: solid 1px rgba($border-color, 0.5);
  }

  .label .title {
    display: inline-block;
    width: calc(100% - 52px);
    height: 26px;
    line-height: 26px;
    vertical-align: top;
    font-size: 13px;
    color: $text-color;
  }

  .label .title .name {
    display: inline-block;
    width: calc(100% - 52px);
    vertical-align: inherit;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .button-icon {
    display: inline-block;
    width: 10px;
    height: 26px;
    opacity: 0.125;
  }

  .button-icon.lock {
    width: 8px;
  }

  .expand-button {
    display: inline-block;
    width: 26px;
    height: 26px;
    text-align: center;
    vertical-align: top;
  }

  .button-icon {
    width: 10px;
    height: 10px;
    vertical-align: baseline;
  }

  .select-handler {
    display: inline-block;
    width: 26px;
    height: 26px;
    text-align: center;
  }

  .select-handler-icon {
    display: inline-block;
    width: 8px;
    height: 26px;
    color: $text-color-gray;
    opacity: 0.25;
  }

  &.is-selected>.label .select-handler-icon {
    color: $primary-color;
    opacity: 1;
  }
  &.is-selected-ancestor>.label .select-handler-icon {
    width: 6px;
    color: $primary-color;
    opacity: 1;
  }
}
</style>
